home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dd / dbuglib.asm < prev    next >
Assembly Source File  |  1994-02-06  |  9KB  |  260 lines

  1. ;         CSYMFMT
  2.  
  3. ;         objfile "dbuglib.o"
  4. ;         addsym
  5.  
  6. ;         incdir  "include:"
  7.  
  8.         include "exec/types.i"
  9.         include "exec/tasks.i"
  10.         include "exec/execbase.i"
  11.         include "exec/memory.i"
  12.         include "dos/dos.i"
  13.         include "dos/dosextens.i"
  14.         include "dos/doshunks.i"
  15.  
  16. ;         include "lvo/exec.lvo"
  17. ;         include "lvo/dos.lvo"
  18.  
  19.     IFD BARFLY
  20.         BOPT    h-,l-,a+,f+,O-,wo-,ws-
  21.         SUPER
  22.     ENDC
  23.  
  24. ********************************************************************************
  25.  
  26. sBase        equ    4
  27.  
  28. EXEC        MACRO
  29.         xref    _LVO\1
  30.         move.l    a6,-(sp)
  31.         move.l    sBase,a6
  32.         jsr    _LVO\1(a6)
  33.         move.l    (sp)+,a6
  34.         ENDM
  35.  
  36. DOS        MACRO
  37.         xref    _LVO\1
  38.         move.l    a6,-(sp)
  39.         move.l    dBase,a6
  40.         jsr    _LVO\1(a6)
  41.         move.l    (sp)+,a6
  42.         ENDM
  43.  
  44. ************************************************************************
  45.  
  46. * Memory Allocation
  47.  
  48. memList     dc.l    0
  49.  
  50.         XDEF    _MallocAny
  51. _MallocAny    move.l    8(sp),d1
  52.         bra.s    Malloc
  53.  
  54.         XDEF    _MallocChip
  55. _MallocChip    moveq.l #MEMF_CHIP,d1
  56.         bra.s    Malloc
  57.         XDEF    _MallocFast
  58. _MallocFast    moveq.l #MEMF_FAST,d1
  59.         bra.s    Malloc
  60.         XDEF    _MallocPublic
  61. _MallocPublic    moveq.l #MEMF_PUBLIC,d1
  62.  
  63. Malloc        or.l    #MEMF_CLEAR,d1
  64.         move.l    4(sp),d0
  65.         addq.l    #8,d0            ; allocate 8 extra bytes (link,size)
  66.         move.l    d0,-(sp)
  67.         EXEC    AllocMem
  68.         move.l    (sp)+,d1
  69.         tst.l    d0
  70.         beq.s    MallocError
  71.         move.l    d0,a0
  72.         move.l    memList,(a0)+        ; link into memList
  73.         move.l    d0,memList
  74.         move.l    d1,(a0)+        ; store size, also
  75.         move.l    a0,d0
  76.         rts
  77.  
  78. MallocError    moveq    #0,d0
  79.         rts
  80.  
  81.         XDEF    _Free
  82. _Free        move.l    4(sp),a1
  83.         subq.l    #8,a1
  84.         lea    memList,a0
  85. .find        move.l    (a0),d0         ; link ahead
  86.         beq.s    .exit            ; ignore if not found
  87.         cmp.l    d0,a1            ; found block pointing to me?
  88.         beq.s    .found
  89.         move.l    d0,a0
  90.         bra.s    .find
  91. .found        move.l    (a1),(a0)        ; unlink from memList
  92.         move.l    4(a1),d0
  93.         EXEC    FreeMem
  94. .exit        rts
  95.  
  96.  
  97.         XDEF    _CleanMem
  98. _CleanMem    move.l    memList,d0
  99.         beq.s    .exit2            ; if memory list is NULL
  100.         move.l    d0,a1
  101.         move.l    (a1),memList        ; unlink memory from list
  102.         move.l    4(a1),d0        ; fetch the size
  103.         EXEC    FreeMem         ; free it
  104.         bra.s    _CleanMem        ; do entire list
  105. .exit2        rts
  106.  
  107. ********************************************************************************
  108.  
  109.         XDEF    debugSR,debugPC,debugD0,debugA7
  110. debugSR     dc.w    0
  111. debugPC     dc.l    0
  112. debugD0     ds.l    8
  113. debugA0     ds.l    7
  114. debugA7     dc.l    0
  115.  
  116.         XREF    _debugStack,_debugStackTop
  117.         XREF    _thisProcess,_thisCli,_exeCommandName,_commandNameSave,_systemTrapHandler
  118.         XREF    _programState,_programSR,_programPC,_programD0,_programA7,_programStack,_programStackTop
  119.  
  120. ;
  121. ; EnterProgram
  122. ;
  123. ; Synopsis:
  124. ;    This subroutine switches from debugger context to program context.
  125. ;    Program context proceeds until an Exec Exception occurs.  When this
  126. ;    happens, the Exception # from the top of stack is saved in programState,
  127. ;    and debugger mode is entered.  EnterProgram then returns to its 'C'
  128. ;    caller.  The program state variables reflect the new values, etc.
  129. ;
  130.         XDEF    _EnterProgram
  131. _EnterProgram    move.l    a5,-(sp)
  132.         lea    Super,a5
  133.         EXEC    Supervisor
  134.         move.l    (sp)+,a5
  135.         rts
  136.  
  137. ;
  138. ; This routine is entered in supervisor mode.  This means the debugger's SR (word) and
  139. ; PC (LONG - rts instruction at end of EnterDebugger) are on the top of the stack.
  140. ; But this is the system stack and not the debugger's - that's in USP (IMPORTANT).
  141. ;
  142. ; Normally, _LVOSupervisor initiated routines exit via RTE directly back to the
  143. ; caller.  In this case, we will pop the debugger's SR and PC from the stack and
  144. ; save them.  We will also save the d0-d7/a0-a6 registers and USP (debugger's A7).
  145. ; We then push the program's SR and PC on the stack, load its register set from
  146. ; RAM variables, and RTE.  The RTE then starts executing the PROGRAM - this means
  147. ; that the task will be used by the target program until the debugger somehow gains
  148. ; control again.
  149. ;
  150. ; So far, the methodology of "swapping contexts" from debugger to program state has
  151. ; been described.  While in program state, the program might do various OS operations
  152. ; that would make the debugger not-transparent.  Since the program and debugger are
  153. ; sharing the same task, the debugger needs its own stack so the program won't see/trash
  154. ; values that would crash the debugger.  As well, there are various CLI and TASK structure
  155. ; fields that are set up by the OS for the debugger so the debugger needs to set those
  156. ; up for the program's needs.  Thus a full context switch involves swapping SR, PC, registers,
  157. ; AND OS structure fields.
  158. ;
  159. ; Notes:
  160. ;    Debugger must be cautious about using resources that might be required by the
  161. ;    program - signal bits are an obvious gotcha.
  162. ;
  163. ;    Because we are only diddling the SR and PC on the top of the stack, we should
  164. ;    not have to care about what CPU model we are on.  Leave the advanced stack
  165. ;    frames alone and let the processor do the right thing when we RTE.
  166. ;
  167. Super        ori.w    #$700,sr        ; disable interrupts during supervisor mode
  168.     ; first save debugger state
  169.         move.w    (sp)+,debugSR
  170.         move.l    (sp)+,debugPC
  171.         movem.l d0-d7/a0-a6,debugD0
  172.         move.l    usp,a0
  173.         move.l    a0,debugA7        ; all registers are trashable from here down
  174.     ; then setup program OS state
  175.         lea    _exeCommandName,a2
  176.         move.l    a2,d0
  177.         lsr.l    #2,d0
  178.         move.l    _thisCli,a2
  179.         move.l    d0,cli_CommandName(a2)    ; So argv[0] works :)
  180.         move.l    _thisProcess,a2
  181.         move.l    _programStack,TC_SPLOWER(a2)     ; set task's TC_stack fields
  182.         add.l    _programStackTop,d0
  183.         addq.l    #2,d0
  184.         move.l    d0,TC_SPUPPER(a2)    ; upper/lower so stack bounds checking code works
  185.  
  186.     ; now install trap handler so exception gets MY attention!!!
  187.     ; this may break with debugged programs that install their own (and don't follow the rules) ...
  188.         lea    TrapHandler,a1
  189.         move.l    a1,TC_TRAPCODE(a2)    ; stuff trap code handler
  190.     ; now setup program registers and supervisor-style stack
  191.         move.l    _programA7,a1
  192.         move.l    a1,usp
  193.         movem.l _programD0,d0-d7/a0-a6     ; all registers are program's now, beware!
  194.         move.l    _programPC,-(sp)     ; program counter
  195.         move.w    _programSR,-(sp)     ; status register
  196.         rte                ; EXECUTE PROGRAM
  197.  
  198. ;
  199. ; The program has executed until an exception occured.    The Exec exception handlers cause the
  200. ; exception # to be pushed on the stack, followed by the standard SR, PC supervisor stack.
  201. ; Cleverly, the STATE_ equates in the main program just happen to be the same as the
  202. ; exception #'s :)
  203. ;
  204. ; What we want to do is to go back into debugger context so the debugger can report on
  205. ; the occurance of the exception.  This involves saving the exception #, SR, and PC
  206. ; from the stack in the programState, programSR, and programPC variables.  The program's
  207. ; register set is saved to RAM, as well as the pertinent OS structure fields.  The debugger's
  208. ; register set and environment is restored and the RTE returns to the rts instruction at
  209. ; the end of EnterProgram().
  210. ;
  211. ; The debugger can cause the program to generate an exception - this is the key to making things
  212. ; like stepping and breakpoints possible.  An elegant solution for stepping is for the debugger
  213. ; to set bit 15 of programSR.  Each time EnterProgram is called, it will execute one instruction
  214. ; and then generate a STATE_TRACE exception.  Tracing will cease when the debugger clears bit
  215. ; 15 of programSR.  Breakpoints are implemented by replacing the instruction at the desired
  216. ; address with an ILLEGAL ($4afc) opcode.  When EnterProgram is called, the program will execute
  217. ; until the ILLEGAL instruction is encountered.  Then the STATE_ILLEGAL exception will occur
  218. ; and the debugger will regain control.
  219. ;
  220. ; Other tricks:
  221. ;    What happens when the program runs until it terminates?  This is a special case where
  222. ;    no exception would be generated!  The trick is for the debugger to push the address
  223. ;    of an illegal instruction on the program's stack before initially executing the
  224. ;    program.  All programs exit to the CLI by RTS!    Thus when the program does RTS,
  225. ;    it executes ILLEGAL right away and the debugger gains control.    The exitcode of
  226. ;    the program will be in programD0 and the PC will point at the ILLEGAL.
  227. ;
  228. TrapHandler    move.l    (sp)+,_programState
  229.  
  230.     ; Save program state
  231.         move.w    (sp)+,_programSR
  232.         move.l    (sp)+,_programPC
  233.         movem.l d0-d7/a0-a6,_programD0
  234.         move.l    usp,a1
  235.         move.l    a1,_programA7             ; registers are scratch from here down
  236.  
  237.     ; Restore debugger state
  238.         move.l    debugA7,a1
  239.         move.l    a1,usp
  240.         move.l    _thisProcess,a2
  241.         move.l    _debugStack,TC_SPLOWER(a2)
  242.         move.l    _debugStackTop,TC_SPUPPER(a2)
  243.         move.l    _systemTrapHandler,TC_TRAPCODE(a2)
  244.         move.l    _thisCli,a2
  245.         move.l    _commandNameSave,cli_CommandName(a2)
  246.         move.l    debugPC,-(sp)
  247.         move.w    debugSR,-(sp)
  248.         movem.l debugD0,d0-d7/a0-a6
  249.         rte
  250.  
  251.  
  252. ************************************************************************
  253.  
  254.         XDEF    _TargetExit
  255. _TargetExit    dc.w    $4afc            ; ILLEGAL instruction
  256.  
  257. ************************************************************************
  258.  
  259.         END
  260.